//
// Created on 2025/6/20.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#include "socket_server.h"
#include <fcntl.h>
#include <sys/select.h>

bool SocketServer::startServer() {
    // 1. 创建 socket
    server_fd_ = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd_ < 0) {
#if OHOS_PLATFORM
        OH_LOG_ERROR(LOG_APP, "Socket creation failed.");
#else
        printf("Socket creation failed.");
#endif
        return false;
    }
    // 2. 设置为非阻塞
    int flags = fcntl(server_fd_, F_GETFL, 0);
    fcntl(server_fd_, F_SETFL, flags | O_NONBLOCK);

    // 3. 设置服务器地址
    struct sockaddr_in server_address;
    memset(&server_address, 0, sizeof(server_address));
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(SERVER_PORT);
    //     address.sin_addr.s_addr = INADDR_ANY; //绑定所有接口
    inet_pton(AF_INET, SERVER_IP, &server_address.sin_addr); // 确保绑定到本机回环

    // 4. 绑定 socket
    if (bind(server_fd_, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {
        int err = errno;
#if OHOS_PLATFORM
        OH_LOG_ERROR(LOG_APP, "Bind failed. errno=%{public}d: %{public}s", err, strerror(err));
#else
        printf("Bind failed. errno=%d: %s", err, strerror(err));
#endif
        close(server_fd_);
        return false;
    }
#if OHOS_PLATFORM
    OH_LOG_INFO(LOG_APP, "SocketServer Successfully bound to port %{public}d", SERVER_PORT);
#else
    printf("SocketServer Successfully bound to port %d", PORT);
#endif
    // 4. 监听连接
    if (listen(server_fd_, 10) < 0) {
#if OHOS_PLATFORM
        OH_LOG_ERROR(LOG_APP, "Listen failed.");
#else
        printf("Listen failed.");
#endif
        close(server_fd_);
        return false;
    }
#if OHOS_PLATFORM
    OH_LOG_INFO(LOG_APP, "SocketServer Listening on ip %{public}s: port %{public}d", SERVER_IP, SERVER_PORT);
#else
    printf("SocketServer Listening on ip %s: port %d", "127.0.0.1", PORT);
#endif
    is_running_ = true; // 设置服务器运行状态
    // 5. 循环接受客户端连接
    std::thread(&SocketServer::acceptClients, this).detach();
    return true;
}

void SocketServer::stopServer() {
    if (!is_running_)
        return;
    std::lock_guard<std::mutex> lock(mutex_);
    is_running_ = false; // 标记服务器已关闭
    cv_.notify_all();    // 唤醒所有等待线程

    for (int client_fd : client_sockets_) {
        close(client_fd); // 关闭所有连接的客户端
    }
    client_sockets_.clear();
    // 关闭服务端 socket
    if (server_fd_ != -1) {
        close(server_fd_);
        server_fd_ = -1;
    }
#if OHOS_PLATFORM
    OH_LOG_INFO(LOG_APP, "Server stopped.");
#else
    printf("Server stopped.");
#endif
}

void SocketServer::acceptClients() {
    while (is_running_) {

        // 判断已连接数是否已到最大
        {
            std::lock_guard<std::mutex> lock(mutex_);
            if (client_sockets_.size() >= MAX_CLIENTS) {
                // 超过最大连接，等待一会再尝试
                // or 你也可以直接continue，不接受新连接
                continue;
            }
        }
        sockaddr_in client_addr;
        socklen_t addr_len = sizeof(client_addr);
#if OHOS_PLATFORM
        OH_LOG_INFO(LOG_APP, "SocketServer Waitting Client...");
#else
        printf("SocketServer Waitting Client...");
#endif
        int client_fd = accept(server_fd_, (struct sockaddr *)&client_addr, &addr_len);
        if (client_fd < 0) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                // 使用条件变量+超时等待（替代直接sleep）
                std::unique_lock<std::mutex> lock(mutex_);
                cv_.wait_for(lock, std::chrono::milliseconds(1000), [this] { return !is_running_; });
                continue;
            } else {
                // 其他错误
                OH_LOG_ERROR(LOG_APP, "Accept failed with error: %{public}s", strerror(errno));
                if (errno == EBADF || errno == ENOTSOCK)
                    break; // 致命错误退出
                continue;
            }
        }
#if OHOS_PLATFORM
        OH_LOG_INFO(LOG_APP, "SocketServer New client connected: %{public}s: %{public}d",
                    inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
#else
        printf("SocketServer New client connected: %s: %s", inet_ntoa(client_addr.sin_addr),
               ntohs(client_addr.sin_port));
#endif
        // 判断连接数是否达到最大
        {
            std::lock_guard<std::mutex> lock(mutex_);
            if (client_sockets_.size() >= MAX_CLIENTS) {
                // 达到上限，关闭连接
                close(client_fd);
#if OHOS_PLATFORM
                OH_LOG_INFO(LOG_APP, "拒绝新连接，超过最大连接数");
#else
                printf("拒绝新连接，超过最大连接数\n");
#endif
                continue; // 继续等待其他连接
            } else {
                // 添加客户端
                client_sockets_.push_back(client_fd);
            }
        }

        //     创建一个新线程处理客户端
        std::thread client_thread(&SocketServer::handleClient, this, client_fd, client_addr);
        client_thread.detach(); // 分离线程以便让其独立运行
        break;
    }
}

void SocketServer::handleClient(int client_fd, const sockaddr_in &client_addr) {
    char buffer[1024];
    while (is_running_) {
        ssize_t bytes_received = recv(client_fd, buffer, sizeof(buffer) - 1, 0);
        if (bytes_received > 0) {
            buffer[bytes_received] = '\0'; // 确保字符串结束
#if OHOS_PLATFORM
            OH_LOG_INFO(LOG_APP, "Received from client: %{public}s", buffer);
#else
            printf("Received from client: %s", buffer);
#endif
            ReceivedData receivedData;
            receivedData.message = buffer;
            receivedData.client_ip = inet_ntoa(client_addr.sin_addr);
            receivedData.client_port = ntohs(client_addr.sin_port);

            // 调用回调函数
            if (data_received_callback_) {
                data_received_callback_(receivedData); // 将接收到的数据传递给回调函数
            }

            // 发送回响应给客户端
            std::string response = "Echo: ";
            response += buffer;
            sendData(client_fd, response.c_str());
        } else {
#if OHOS_PLATFORM
            OH_LOG_ERROR(LOG_APP, "Client disconnected or error occurred.");
#else
            printf("Client disconnected or error occurred.");
#endif
            close(client_fd);
            removeClient(client_fd); // 关闭客户端并从列表中删除
            return;
        }
    }
}

void SocketServer::removeClient(int client_fd) {
    std::lock_guard<std::mutex> lock(mutex_);
    auto it = std::remove(client_sockets_.begin(), client_sockets_.end(), client_fd);
    client_sockets_.erase(it, client_sockets_.end());
}

void SocketServer::sendData(int client_fd, const std::string &message) {
    send(client_fd, message.c_str(), message.length(), 0); // 发送数据
}
